package com.dxy.dxyproduct.service.impl;

import com.dxy.dxycommon.utils.KeyUtil;
import com.dxy.dxyproduct.DO.ProductCategory;
import com.dxy.dxyproduct.DO.ProductInfo;
import com.dxy.dxyproduct.VO.ProductCategoryTree;
import com.dxy.dxyproduct.VO.ProductCategoryVO;
import com.dxy.dxyproduct.VO.ProductInfoVO;
import com.dxy.dxyproduct.enums.ResultEnum;
import com.dxy.dxyproduct.exception.ProductException;
import com.dxy.dxyproduct.exception.RollBackException;
import com.dxy.dxyproduct.repository.ProductCategoryRepository;
import com.dxy.dxyproduct.repository.ProductInfoRepository;
import com.dxy.dxyproduct.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductCategoryRepository productCategoryRepository;

    @Autowired
    private ProductInfoRepository productInfoRepository;

    /**
     * 添加分类
     *
     * @param productCategoryVo
     * @return
     */
    @Override
    public String addCategory(ProductCategoryVO productCategoryVo) {
        Integer pId = productCategoryVo.getParentId();
        //查询父类是否存在
        ProductCategory product = productCategoryRepository.findByCategoryId(pId);
        if (product == null && productCategoryVo.getParentId() != 0) {
            throw new ProductException(ResultEnum.CATEGORY_PARENT_NOT_EXIST);
        }
        ProductCategory productCategory = new ProductCategory();
        String categoryType = KeyUtil.genUniqueKey();
        productCategory.setCategoryType(new BigInteger(categoryType));
        BeanUtils.copyProperties(productCategoryVo, productCategory);
        productCategoryRepository.save(productCategory);
        return categoryType;
    }

    /**
     * 删除分类
     *
     * @param categoryType
     * @return
     */
    @Override
    @Transactional(rollbackFor = RollBackException.class)
    public int deleteCategory(BigInteger categoryType) {
        //存在子类不能删除
        ProductCategory productCategory = productCategoryRepository.findByCategoryType(categoryType);
        if (productCategory != null) {
            List<ProductCategory> productCategoryList = productCategoryRepository.findByParentId(productCategory.getCategoryId());
            if (productCategoryList.size() != 0) {
                throw new ProductException(ResultEnum.CATEGORY_DELETE_FAIL_OF_HAS_CHILDREN);
            }
        } else {
            throw new ProductException(ResultEnum.CATEGORY_NOT_EXIST);
        }
        return productCategoryRepository.deleteByCategoryType(categoryType);
    }

    /**
     * 更新分类
     *
     * @param productCategoryVo
     */
    @Override
    @Modifying
    @Transactional(rollbackFor = Exception.class)
    public void updateCategory(ProductCategoryVO productCategoryVo) {
        //判断父类ID是否存在
        int pId = productCategoryVo.getParentId();
        boolean b = productCategoryRepository.existsByCategoryId(pId);
        if (b || pId == 0) {
            ProductCategory productCategory = productCategoryRepository.findByCategoryId(productCategoryVo.getCategoryId());
            BeanUtils.copyProperties(productCategoryVo, productCategory);
            productCategoryRepository.save(productCategory);
        } else {
            throw new ProductException(ResultEnum.CATEGORY_PARENT_NOT_EXIST);
        }

    }

    /**
     * 查询分类列表
     *
     * @return
     */
    @Override
    public List<ProductCategoryTree> listCategory() {
        List<ProductCategory> productCategoryList = productCategoryRepository.findByParentId(0);
        List<ProductCategoryTree> productCategoryTreeList = new ArrayList<>();
        for (ProductCategory productCategory : productCategoryList) {
            int fId = productCategory.getCategoryId();
            ProductCategoryTree productCategoryTree = new ProductCategoryTree();
            if (productCategory.getParentId() == 0) {
                BeanUtils.copyProperties(productCategory, productCategoryTree);
                List<ProductCategory> subCategory = productCategoryRepository.findByParentId(fId);
                if (subCategory.size() != 0) {
                    productCategoryTree.setSubCategory(subCategory);
                }
            }
            productCategoryTreeList.add(productCategoryTree);
        }
        return productCategoryTreeList;
    }

    /**
     * 创建产品
     *
     * @param productInfoVO
     * @return
     */
    @Override
    public String addProduct(ProductInfoVO productInfoVO) {
        String productId = KeyUtil.genUniqueKey();
        ProductInfo productInfo = new ProductInfo();
        BeanUtils.copyProperties(productInfoVO, productInfo);
        productInfo.setProductId(productId);
        productInfoRepository.save(productInfo);
        return productId;
    }

    /**
     * 更新商品
     *
     * @param productInfoVO
     * @return
     */
    @Override
    public String updateProduct(ProductInfoVO productInfoVO) {
        String productId = productInfoVO.getProductId();
        ProductInfo productInfo = new ProductInfo();
        BeanUtils.copyProperties(productInfoVO, productInfo);
        productInfo.setProductId(productId);
        if (productId != null && productInfoRepository.findByProductId(productId) != null) {
            productInfoRepository.save(productInfo);
        } else {
            throw new ProductException(ResultEnum.PRODUCT_NOT_EXIST);
        }
        return productId;
    }

    /**
     * 删除商品
     *
     * @param productId
     * @return
     */
    @Override
    @Transactional(rollbackFor = RollBackException.class)
    public int deleteProduct(String productId) {
        log.info("=========="+productId+"=========");
        if (productInfoRepository.findByProductId(productId) == null) {
            throw new ProductException(ResultEnum.PRODUCT_NOT_EXIST);
        }
        return productInfoRepository.deleteByProductId(productId);
    }

    /**
     * 查询商品
     *
     * @param productId
     * @return
     */
    @Override
    public ProductInfoVO selectProduct(String productId) {
        ProductInfo productInfo = productInfoRepository.findByProductId(productId);
        if (productInfo == null) {
            throw new ProductException(ResultEnum.PRODUCT_NOT_EXIST);
        }
        ProductInfoVO productInfoVO = new ProductInfoVO();
        BeanUtils.copyProperties(productInfo, productInfoVO);
        return productInfoVO;
    }

    /**
     * 查询商品
     *
     * @return
     */
    @Override
    public Page<ProductInfo> listProduct(Integer page, Integer size, Integer searchStatus, String searchName) {
        Pageable pageable = new PageRequest(page-1, size, Sort.Direction.DESC, "createTime");
        //条件查询
        Specification specification = (Specification) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(searchName)) {
                predicates.add(cb.like(root.get("productName"), "%" + searchName + "%"));
            }
            if (searchStatus != null) {
                predicates.add(cb.ge(root.get("productStatus"), searchStatus));
            }

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        Page<ProductInfo> productInfos = productInfoRepository.findAll(specification, pageable);
        return productInfos;
    }


}
